class PipeColumn(object):
    def __init__(self, _pipeArray, _boundaryArray,_insulating) -> None:
        self.pipeArray = _pipeArray # 初始管道列
        self.boundaryArray = _boundaryArray # 边界[minx, miny, maxx, maxy]
        self.startx = self.boundaryArray[0]
        self.starty = self.boundaryArray[1]
        self.startz = self.boundaryArray[2]
        self.size = len(_pipeArray)
        self.width = self.pipeArray[0][2] # 以管道列第一段管道的尺寸为栅格化标准
        self.height = self.pipeArray[0][3]
        self.insulatingSpace = _insulating
        self.realWidth = self.width + 2 * self.insulatingSpace # 考虑绝缘层的管道尺寸
        self.realHeight = self.height + 2 * self.insulatingSpace
        self.gridArray = [] # [起点, 中间点, 终点]栅格坐标数组
        self.shortPipe = []
        self.Point_to_Grid() # 获取栅格化之后的管道列
        self.routeArray = [] # A*栅格路径转坐标之后的管道列
        

    def get_width_heigh(self):
        return [self.width, self.height]
        
    def getGrid(self):
        return self.gridArray

    def getRoute(self):
        return self.routeArray

    def getBoundary(self):
        return self.boundaryArray

    def getGridBoundary(self):
        return [int((self.boundaryArray[3] - self.startx) / self.width), 
        int((self.boundaryArray[4] - self.starty) / self.width), 
        int((self.boundaryArray[5] - self.startz) / self.height)]

    def isShort(self, startgrid, endgrid)->bool:
        if startgrid[0] == endgrid[0] and startgrid[1] == endgrid[1] and startgrid[2] == endgrid[2]:
            return True
        return False

    def Point_to_Grid(self):
        i = 0
        if self.size & 1 == True:
            while i < (self.size-1):
                start_point = self.pipeArray[i][0]
                mid_point = self.pipeArray[i][1]
                end_point  = self.pipeArray[i+1][1]
                # 栅格x, y坐标由管道宽度决定，栅格z坐标由管道高度决定
                start_grid = self.cord_to_grid(start_point, self.realWidth, self.realHeight)
                end_grid = self.cord_to_grid(end_point, self.realWidth, self.realHeight)
                mid_grid = self.cord_to_grid(mid_point, self.realWidth, self.realHeight)
                if self.isShort(start_grid, mid_grid):
                    self.shortPipe.append(self.pipeArray[i])
                if self.isShort(mid_grid, end_grid):
                    self.shortPipe.append(self.pipeArray[i+1])
                self.gridArray.append([start_grid, end_grid, mid_grid]) # 存储管道的栅格坐标 [起点、终点、中间点] 
                i += 2
            start_point = self.pipeArray[-1][0]
            end_point  = self.pipeArray[-1][1]
            start_grid = self.cord_to_grid(start_point, self.realWidth, self.realHeight)
            end_grid = self.cord_to_grid(end_point, self.realWidth, self.realHeight)
            if self.isShort(start_grid, end_grid):
                self.shortPipe.append(self.pipeArray[-1])
            self.gridArray.append([start_grid, end_grid])
        else:
            while i < self.size:
                start_point = self.pipeArray[i][0]
                mid_point = self.pipeArray[i][1]
                end_point  = self.pipeArray[i+1][1]
                # 栅格x, y坐标由管道宽度决定，栅格z坐标由管道高度决定
                start_grid = self.cord_to_grid(start_point, self.realWidth, self.realHeight)
                end_grid = self.cord_to_grid(end_point, self.realWidth, self.realHeight)
                mid_grid = self.cord_to_grid(mid_point, self.realWidth, self.realHeight)
                if self.isShort(start_grid, mid_grid):
                    self.shortPipe.append(self.pipeArray[i])
                if self.isShort(mid_grid, end_grid):
                    self.shortPipe.append(self.pipeArray[i+1])
                self.gridArray.append([start_grid, end_grid, mid_grid]) # 存储管道的栅格坐标 [起点、终点、中间点] 
                i += 2

    def Grid_to_Point(self, AstarGrid):
        # A*输出的路径栅格长度应当与管道列中管道段数量相等
        for i in range(self.size):
            # 获取当前管道段的宽高
            width = self.pipeArray[i][2]
            height = self.pipeArray[i][3]
            Aroute = AstarGrid[i]
            # 栅格转坐标, 把A*路径[起点...中间点]或者[中间点...终点]全部转化为一条条[起点，终点，宽，高，角度(None)]
            for j in range(len(Aroute)-1):
                self.routeArray.append(
                    self.grid_to_cord(Aroute[j], Aroute[j+1], self.realWidth, self.realHeight, width, height)
                    )


    # 坐标转栅格
    # 输入：坐标, 量化宽度, 量化高度
    def cord_to_grid(self, cord, width, height):
        return [int((cord[0] - self.startx)/width), int((cord[1] - self.starty)/width), int((cord[2] - self.startz)/height)]
    
    # 栅格转管道段坐标
    # 输入：起点栅格, 终点栅格, 量化宽度, 量化高度, 管道宽度, 管道高度
    def grid_to_cord(self, Startgrid, Endgrid, unitWidth, unitHeight, pipeWidth, pipeHeight):
        return [[Startgrid[0]*unitWidth + self.startx, Startgrid[1]*unitWidth + self.starty, Startgrid[2]*unitHeight + self.startz], 
        [Endgrid[0]*unitWidth + self.startx, Endgrid[1]*unitWidth + self.starty, Endgrid[2]*unitHeight  + self.startz], 
        pipeWidth, pipeHeight, None]
    